package com.zhang.common.redis.config;

import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.Assert;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @Class com.zhang.common.redis.config
 * @Author zhang
 * @Date 2025/9/15 14:48
 * @Description Redis使用FastJson序列化
 **/
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {

    /**
     * Jackson ObjectMapper（当前类未实际使用，可能为预留字段）
     * 如需切换为 Jackson 实现，可激活此字段
     */
    @SuppressWarnings("unused")
    private ObjectMapper objectMapper = new ObjectMapper();

    /** 默认字符集 UTF-8 */
    public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;

    /** 目标对象类型（反序列化时用于类型转换） */
    private Class<T> clazz;

    static {
        // 启用自动类型识别（需谨慎！可能引发安全漏洞）
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
    }

    /**
     * 构造序列化器
     * @param clazz 目标对象的 Class 类型（反序列化时需要）
     */
    public FastJson2JsonRedisSerializer(Class<T> clazz) {
        super();
        this.clazz = clazz;
    }

    /**
     * 序列化对象为字节数组
     * @param t 待序列化对象（允许为 null）
     * @return 序列化后的字节数组（null 返回空数组）
     * @throws SerializationException 序列化失败时抛出
     */
    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }
        return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }

    /**
     * 反序列化字节数组为对象
     * @param bytes 待反序列化的字节数组（允许为 null 或空数组）
     * @return 反序列化后的对象（输入为空时返回 null）
     * @throws SerializationException 反序列化失败时抛出
     */
    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);

        return JSON.parseObject(str, clazz);
    }

    /**
     * 设置备用 Jackson ObjectMapper
     * （当前类未实际使用，保留用于可能的扩展）
     * @param objectMapper 不能为 null
     */
    public void setObjectMapper(ObjectMapper objectMapper) {
        Assert.notNull(objectMapper, "'objectMapper' must not be null");
        this.objectMapper = objectMapper;
    }

    /**
     * 获取 Jackson 类型信息（当前类未实际使用）
     * @param clazz 目标类型
     * @return Jackson JavaType 对象
     */
    protected JavaType getJavaType(Class<?> clazz) {
        return TypeFactory.defaultInstance().constructType(clazz);
    }
}

